home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-06-22 | 17.5 KB | 646 lines | [TEXT/MPS ] |
- // Sample field protection plugin, using the industry standart ROT13 algorithm.
-
-
- #include "ArrangeCallbacks.h"
- #include "PluginLibrary.h"
-
- #include <Dialogs.h>
- #include <StandardFile.h>
- #include <string.h>
- #include <Folders.h>
- #include <TextUtils.h>
- #include <Resources.h>
- #include <AppleEvents.h>
- #include <PLStringFuncs.h> /* some special string handling stuff */
-
- #if defined (__MWERKS__) && defined (PLUGIN_GLOBALS)
- #include "A4Stuff.h"
- #endif
-
- #define ModuleRsrcID -0x8000
-
- #define OurModuleID 0x72300000 //Unique module ID assigned by Phil Meyer
- //#define OurModuleID 0x70001513 // Unique module ID; replace with a value
- // obtained from Common Knowledge.
- #define baseCmdCode OurModuleID
-
- #define pluginName "Protect" // controls our name in the About menu
- #define aboutCmdCode (baseCmdCode + 0)
- #define reformatText (baseCmdCode + 1)
-
- #if defined (__MWERKS__) && defined (PLUGIN_GLOBALS)
- #define SetupA4 long lOldA4 = SetCurrentA4 ();
- #define TearDownA4 SetA4 (lOldA4);
- #define UnloadSegs UnloadSegsFunc ();
-
- static void UnloadSegsFunc ();
- #else
- #define SetupA4
- #define TearDownA4
- #define UnloadSegs
- #endif //__MWERKS__
-
- typedef struct {
- const ArrangeCallbackTbl* calls;
- } myprefs;
-
- class Plugin
- {
- public:
- Plugin(const ArrangeCallbackTbl* theCalls);
- ~Plugin();
-
- arHookResult ClickNotify( arClickLocation loc, Point where, Short modifiers,
- Short clickCount, arNoteID note, arFieldID field,
- arPathID path );
- arHookResult KeyNotify ( Short theChar, Short key, Short modifiers );
- arHookResult MenuNotify ( Integer commandCode, Integer commandParam,
- Short modifiers );
- void AboutToMenu();
- arHookResult FieldNotify( arNoteID note, arFieldID field, arFieldAction action,
- const char* choiceText );
- void TopicNotify( arTopicID newTopic, arWindowID newWindow,
- arTopicAction action );
- void TickNotify ( );
- arHookResult FileNotify ( arFileAction action );
- arHookResult QuitNotify ( );
- void ATMNotify ( );
- void FormatTheNotes ( );
-
- private:
- const ArrangeCallbackTbl* calls; // callback table
- myprefs theprefs;
- }; // Plugin
-
-
- /*************************************************************************/
- /**************************** Main entry point ***************************/
- /*************************************************************************/
-
- /* Root entry point for the module - must be the first function in the
- * file, so that the linker will place it first in the code segment.
- * This is the routine which Arrange calls at application startup time
- * (and again at quit time).
- *
- * Most plug-ins will not need to modify this routine or the Hook functions
- * immediately following. All customization can be done in the "Plugin"
- * section (below).
- */
- extern "C" Integer main( ModuleParamBlock *pb, pModuleRootAction action,
- Integer /*p1*/ )
- {
- SetupA4;
-
- Integer lResult = 0;
-
- /* Extract the callback table from our parameter block, and coerce it
- * to the extended Arrange table.
- */
- ArrangeCallbackTbl* calls = (ArrangeCallbackTbl*)(pb->calls);
-
- Assert (sizeof (Byte) == 1);
- Assert (sizeof (Short) == 2);
- Assert (sizeof (Integer) == 4);
- Assert (sizeof (Float) == 8);
-
- switch (action)
- {
- case mrLoad:
- {
- // Allocate memory and create a new Plugin object.
- void* storage = calls->mem->AllocMem( sizeof(Plugin),
- amFreeStore | amErrIfNoMem );
- pb->moduleRefcon = uInteger(new(storage) Plugin(calls));
- lResult = 1;
- }
- break;
-
- case mrUnload:
- {
- /* Dispose of the Plugin object and release the memory
- * it occupies.
- */
- delete (Plugin*)(pb->moduleRefcon);
- calls->mem->DeallocMem((void*)(pb->moduleRefcon), amFreeStore);
- lResult = 0;
- }
- break;
-
- case mrFindEntry:
- default:
- {
- /* This module contains no extended entry points, so we always
- * return 0 for the mrFindEntry message. Most plug-ins will not
- * use extended entry points.
- */
- lResult = 0;
- }
- break;
-
- } // switch (action)
-
- TearDownA4;
- return lResult;
- } // main
-
- #if defined (__MWERKS__) && defined (PLUGIN_GLOBALS)
- #pragma segment PluginLib
- static void PluginLibSeg (void)
- {
- }
-
- #pragma segment Main
- static void UnloadSegsFunc ()
- {
- // Put segment unloading code here.
- // Do NOT use UnloadSeg!
- //UnloadA4Seg (PluginLibSeg);
- }
- #endif //__MWERKS__ && PLUGIN_GLOBALS
-
- /* These hook functions simply pass control to the appropriate function
- * in the Plugin object.
- */
- static arHookResult OurClickHook( ModuleParamBlock* pb, arClickLocation loc,
- Point where, pShort modifiers, pShort clickCount,
- arNoteID note, arFieldID field,
- arPathID path ENDP )
- {
- SetupA4;
- arHookResult eResult = ((Plugin*)(pb->moduleRefcon))->ClickNotify( loc, where, modifiers,
- clickCount, note, field,
- path );
- TearDownA4;
- return eResult;
- }
-
-
- static arHookResult OurKeyHook( ModuleParamBlock* pb, pShort theChar, pShort key,
- pShort modifiers ENDP )
- {
- SetupA4;
- arHookResult eResult = ((Plugin*)(pb->moduleRefcon))->KeyNotify(theChar, key, modifiers);
- TearDownA4;
- return eResult;
- }
-
-
- static arHookResult OurMenuHook( ModuleParamBlock* pb, Integer commandCode,
- Integer commandParam, pShort modifiers ENDP )
- {
- SetupA4;
- arHookResult eResult = ((Plugin*)(pb->moduleRefcon))->MenuNotify( commandCode, commandParam,
- modifiers );
- TearDownA4;
- return eResult;
- }
-
-
- void OurATMHook(ModuleParamBlock* pb)
- {
- ((Plugin*)(pb->moduleRefcon))->AboutToMenu();
- } // OurATMHook
-
-
- static arHookResult OurFieldHook( ModuleParamBlock* pb, arNoteID note,
- arFieldID field, arFieldAction action,
- const char* choiceText ENDP )
- {
- SetupA4;
- arHookResult eResult = ((Plugin*)(pb->moduleRefcon))->FieldNotify( note, field, action,
- choiceText );
- TearDownA4;
- return eResult;
- }
-
-
- static void OurTopicHook( ModuleParamBlock* pb, arTopicID newTopic,
- arWindowID newWindow, arTopicAction action ENDP )
- {
- SetupA4;
- ((Plugin*)(pb->moduleRefcon))->TopicNotify(newTopic, newWindow, action);
- TearDownA4;
- }
-
-
- static void OurTickHook(ModuleParamBlock* pb ENDP)
- {
- SetupA4;
- ((Plugin*)(pb->moduleRefcon))->TickNotify();
- TearDownA4;
- }
-
-
- static arHookResult OurFileHook(ModuleParamBlock* pb, arFileAction action ENDP)
- {
- SetupA4;
- arHookResult eResult = ((Plugin*)(pb->moduleRefcon))->FileNotify(action);
- TearDownA4;
- return eResult;
- }
-
-
- static arHookResult OurQuitHook(ModuleParamBlock* pb ENDP)
- {
- SetupA4;
- arHookResult eResult = ((Plugin*)(pb->moduleRefcon))->QuitNotify();
- TearDownA4;
- return eResult;
- }
-
- /*************************************************************************/
- /********************************* Plugin ********************************/
- /*************************************************************************/
-
- /* Construct a Plugin object. This is called once, from the OurModuleRoot
- * function, when the module is initialized (i.e. at application startup time).
- */
- Plugin::Plugin(const ArrangeCallbackTbl* theCalls)
- {
- short thelength;
- arDocumentPtr theCurDoc;
- arDocumentPtr thePrefDoc;
- Str255 ourname;
- Handle temph;
-
- // Record the callback table for future use.
- calls = theCalls;
-
- /* These commands, if un-commented-out, register this plugin to be called
- * by Arrange when various events occur. For example, if you un-comment-out
- * the call to SetClickHook, then Plugin::ClickNotify will be called
- * whenever the user clicks in any of the locations described in the
- * arClickLocation enum.
- */
- // calls->ui->SetClickHook(OurClickHook, 0, true);
- // calls->ui->SetKeyHook (OurKeyHook, 0, true, charFilter, keyFilter, modFilter);
- // calls->ui->SetMenuHook (OurMenuHook, 0, true, whichCommand);
- // calls->ui->SetFieldHook(OurFieldHook, 0, true, whichField);
- //calls->ui->SetTopicHook(OurTopicHook, 0, true);
- // calls->ui->SetFileHook (OurFileHook, 0, true);
- //calls->ui->SetQuitHook (OurQuitHook, 0, true);
- calls->ui->SetTickHook (OurTickHook, 0, true);
- calls->ui->SetATMHook (OurATMHook, 0, true);
-
- // Add an item to the About Plugins menu for this plugin.
- temph = GetResource('STR ', ModuleRsrcID+1); // "About Protect"
- BlockMove ((Ptr)*temph, (Ptr)(&ourname), 50);
- ourname[ourname[0]+1] = 0; //Make good for C String
- calls->ui->AddMenuItem(mPluginAbout, (char *)(&ourname[1]), 0, aboutCmdCode, 1);
-
- temph = GetResource('STR ', ModuleRsrcID+2); // "Protect Text"
- BlockMove ((Ptr)*temph, (Ptr)(&ourname), 50);
- ourname[ourname[0]+1] = 0; //Make good for C String
- calls->ui->AddMenuItem(mEdit, (char *)(&ourname[1]), 0, reformatText, 2);
-
- calls->ui->SetMenuHook(OurMenuHook, 1, true, aboutCmdCode);
- calls->ui->SetMenuHook(OurMenuHook, 2, true, reformatText);
-
- } // Plugin constructor
-
-
- /* Dispose of a Plugin object. This is called when Arrange terminates. You
- * should free up any data structures which you allocation in the Plugin
- * constructor (above).
- */
- Plugin::~Plugin()
- {
- } // ~Plugin
-
-
- /* This function is called whenever the user clicks in an "interesting place"
- * in a document window. It should return true if we handle the click, false
- * (the normal case) when the click should be passed along to other plug-ins
- * or to Arrange's normal event processing. See the documentation for
- * SetClickHook for more details.
- */
- arHookResult Plugin::ClickNotify( arClickLocation loc, Point where,
- Short modifiers, Short clickCount,
- arNoteID note, arFieldID field,
- arPathID path )
- {
- return false; // Let Arrange handle the event
- } // ClickNotify
-
-
- /* This function is called whenever the user types a key which matches the
- * filters we pass to SetKeyHook in Plugin's constructor. It should return
- * true if we handle the event, false (the normal case) when the event
- * should be passed along to other plug-ins or to Arrange's normal event
- * processing. See the documentation for SetKeyHook for more details.
- */
- arHookResult Plugin::KeyNotify(Short theChar, Short key, Short modifiers)
- {
- return false; // Let Arrange handle the event
- } // KeyNotify
-
- // OK, we get the notes, get their text, and do cool stuff with them!
-
- static Boolean ProtectText(const ArrangeCallbackTbl* calls, Ptr theptr, short* thelength)
- {
- Ptr p;
- char lastChar=0;
- char thechar=0xff;
- char x;
-
- char key[256];
-
- calls->dlg->PromptForString("Enter password", key, 255, false);
-
- short l = *thelength;
-
- p=theptr;
- Boolean IsChanged = false;
-
-
- while (l-- > 0)
- {
- if (*p >= 'A' && *p <= 'Z')
- {
- x = (*p - 'A');
- x = (x + 13) % 26;
-
- *p = 'A' + (x);
- IsChanged = true;
- }
-
- if (*p >= 'a' && *p <= 'z')
- {
- x = (*p - 'a');
- x = (x + 13) % 26;
-
- *p = 'a' + (x);
- IsChanged = true;
- }
-
- p++;
- }
-
- return IsChanged;
- }
-
- void Plugin::FormatTheNotes ( )
- {
- Integer i;
- short whichnote;
- // Determine whether there is a selection and how many notes it contains.
- Integer selCount;
-
- arNoteID selNote;
- arNoteID parentNote;
- arFieldID selField;
- Integer selStart;
- Integer selEnd;
-
- short thecount;
- arFieldID theField;
- arFieldInfo info;
- arNoteInfo thetopicinfo;
- short thelength;
- Str255 tempstr;
- Ptr theptr;
- char TheName[32]="Protecting";
- Boolean firstchange = true;
-
- Str31 promptstr = "Now protecting";
- Handle temph;
-
- temph = GetResource('STR ', ModuleRsrcID+3); // "Now Reformatting Text"
- BlockMove((Ptr)*temph, &promptstr, 32);
-
- promptstr[promptstr[0]+1] = 0;
-
- calls->dlg->DisplayNotify( (const char*)&promptstr[1], nfShowImmediately);
-
- if (!calls->sel->FlushSelection(false))
- {
- calls->dlg->ClearNotify();
- return;
- }
-
- switch (calls->sel->GetSelection(&selNote, &selField, &selStart, &selEnd))
- {
- case stNote:
- case stFieldContents:
- selCount = 1;
- break;
-
- case stMultipleNotes:
- case stMultipleFields:
- selCount = selStart;
- break;
-
- case stField:
- thelength = calls->data->GetFieldTextLen(selNote, selField);
- if (thelength)
- {
- info.versNum = 1;
- calls->sysObj->GetFieldInfo(selField, &info);
- thelength = calls->data->GetFieldTextLen(selNote, selField);
- if (thelength)
- {
- theptr = NewPtr(thelength+1);
- if (!theptr)
- {
- calls->dlg->ClearNotify();
- return;
- }
- thelength = calls->data->GetFieldText(selNote, selField, thelength+1, (char*)theptr);
- if (ProtectText(calls, theptr, &thelength))
- {
- if (firstchange)
- {
- calls->doc->SetupUndo(TheName, true);
- firstchange = false;
- }
-
- calls->data->SetFieldText(selNote, selField, (char*)theptr, thelength, 0);
- calls->sel->FlushSelection(false);
- }
- DisposePtr(theptr);
- }
- }
- calls->dlg->ClearNotify();
- return;
- break;
- case stText: // selected text is treated specially
- thelength = calls->data->GetFieldTextLen(selNote, selField);
- if (thelength)
- {
- theptr = NewPtr(thelength+1);
- if (!theptr)
- {
- calls->dlg->ClearNotify();
- return;
- }
- thelength = calls->sel->GetSelText(thelength+1, (char*)theptr, &selStart, &selEnd);
- thelength = selEnd-selStart;
- *((Ptr)(theptr+selEnd+1)) = 0;
- if (ProtectText(calls, (Ptr)(theptr+selStart), &thelength))
- {
- calls->sel->ReplaceSelText((Ptr)(theptr+selStart), TheName);
- calls->sel->FlushSelection(false);
- }
- DisposePtr(theptr);
- }
- calls->dlg->ClearNotify();
- return;
- break;
- default:
- calls->dlg->ClearNotify();
- return;
-
- } // switch (GetSelection result)
-
- // Iterate over each selected note.
- for (whichnote=0; whichnote<selCount; whichnote++)
- {
- calls->sel->GetSelEntry(whichnote, &selNote, &selField, &parentNote);
- if (selNote != nil)
- {
- calls->notes->GetNoteInfo(selNote, &thetopicinfo);
- thecount = calls->notes->CountNoteFields(selNote);
- for (i=0; i<thecount; i++)
- {
- theField = calls->notes->GetNoteField(selNote, i);
- if (theField!=nil)
- {
- info.versNum = 1;
- calls->sysObj->GetFieldInfo(theField, &info);
- if (info.type==arFTText)
- {
- thelength = calls->data->GetFieldTextLen(selNote, theField);
- if (thelength)
- {
- theptr = NewPtr(thelength+1);
- if (!theptr)
- {
- calls->dlg->ClearNotify();
- return;
- }
- thelength = calls->data->GetFieldText(selNote, theField, thelength+1, (char*)theptr);
- if (ProtectText(calls, theptr, &thelength))
- {
- if (firstchange)
- {
- calls->doc->SetupUndo(TheName, true);
- firstchange = false;
- }
-
- calls->data->SetFieldText(selNote, theField, (char*)theptr, thelength, 0);
- calls->sel->FlushSelection(false);
- }
- DisposePtr(theptr);
- }
- }
- }
- }
- }
-
- } // whichnote loop
- calls->dlg->ClearNotify();
- return;
- }
-
- /* This function is called whenever the user clicks in the menu bar or types
- * a command key, just before processing the event. It does any fixing up
- * of menus which might be necessary based on the current state of affairs.
- */
- void Plugin::AboutToMenu()
- {
- arNoteID selNote;
- arFieldID selField;
- Integer selStart,selEnd;
- arSelType selType = calls->sel->GetSelection( &selNote, &selField,
- &selStart, &selEnd );
-
- Boolean hasSingleSel = ( selType == stNote || selType == stMultipleNotes || selType == stText || selType == stField );
-
- calls->ui->SetMenuItem(mEdit, reformatText, 2, nil, ((selType == stNote) || (selType == stMultipleNotes) || (selType == stText) || (selType == stField)), 0, 0);
-
- }
-
- arHookResult Plugin::MenuNotify( Integer commandCode, Integer commandParam,
- Short modifiers )
- {
- ProcessSerialNumber thepsn;
- arTopicID thistopic;
- arTopicInfo topicinfo;
-
- /* If this is our About menu item, display our about-box dialog and return
- * true to indicate we handled the command.
- */
- if (commandCode == aboutCmdCode)
- {
- Alert(ModuleRsrcID, nil);
- return true;
- }
- if (commandCode == reformatText)
- {
- FormatTheNotes();
- return true;
- }
- return false; // Let Arrange handle the event
-
- } // MenuNotify
-
-
- /* If we register to recieve events for a field by calling SetFieldHook, this
- * function will be called for any events in that field. It should return
- * false in almost all cases. See the documentation for SetFieldHook for
- * more details.
- */
- arHookResult Plugin::FieldNotify( arNoteID note, arFieldID field,
- arFieldAction action, const char* choiceText )
- {
- return false;
- } // FieldNotify
-
-
- /* This function is called whenever the user switches windows or changes
- * the current folder/topic/view in the front window. See the documentation
- * for SetTopicHook for more details.
- */
- void Plugin::TopicNotify( arTopicID newTopic, arWindowID newWindow,
- arTopicAction action )
- {
- } // TopicNotify
-
-
- /* This function is called periodically, whenever Arrange recieves a null
- * event from the Event Manager.
- */
- void Plugin::TickNotify()
- {
- } // TickNotify
-
-
- /* This function is called whenever various file-level events occur. It
- * should return true in almost all cases. See the documentation for
- * SetFileHook for more details.
- */
- arHookResult Plugin::FileNotify(arFileAction action)
- {
- return true;
- } // FileNotify
-
-
- /* This function is called if the user voluntarily quits Arrange. It should
- * return true to allow the user to quit, false to prevent it. See the
- * documentation for SetQuitHook for more details.
- */
- arHookResult Plugin::QuitNotify()
- {
- return true;
- } // QuitNotify
-
-
- /* This function is called whenever the user clicks in the menu bar or types
- * a command key, just before processing the event. It should do any fixing
- * up of menus which might be necessary based on the current state of affairs.
- * See the documentation for SetATMHook for more details.
- */
- void Plugin::ATMNotify()
- {
- } // ATMNotify
-